package com.cloud.oss.minio.Metric;

import com.cloud.oss.minio.config.MinioAutoConfiguration;
import io.minio.MinioClient;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;

/**
 * @author wangjian
 * @version 1.0.0
 * @create 2020年11月11日 11:53
 * @since JDK 1.8
 * Life is so short,do something to make yourself happy,such as coding
 */
@Aspect
@Configuration
@ConditionalOnClass({MinioClient.class, ManagementContextAutoConfiguration.class})
@ConditionalOnEnabledHealthIndicator("minio")
@AutoConfigureAfter(MinioAutoConfiguration.class)
public class MinioMetricConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioMetricConfiguration.class);

    /**
     * 监控下载指标
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @ConditionalOnBean(MinioClient.class)
    @Around("execution(* io.minio.MinioClient.getObject(..))")
    public Object getMeter(ProceedingJoinPoint pjp) throws Throwable {
        long l = System.currentTimeMillis();

        try {
            Object proceed = pjp.proceed();
            LOGGER.info("[minio] Minio Metric Collection, Download metric success. Time consuming:{}", System.currentTimeMillis() - l);
            return proceed;
        } catch (Exception e) {
            LOGGER.error("[minio] Minio Metric Collection, Download metric fail. Time consuming:{}",  System.currentTimeMillis() - l);
            throw e;
        }
    }

    /**
     * 监控上传指标
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @ConditionalOnBean(MinioClient.class)
    @Around("execution(* io.minio.MinioClient.putObject(..))")
    public Object putMeter(ProceedingJoinPoint pjp) throws Throwable {
        long l = System.currentTimeMillis();

        try {
            Object proceed = pjp.proceed();
            LOGGER.info("[minio] Minio Metric Collection, Upload metric success. Time consuming:{}", System.currentTimeMillis() - l);
            return proceed;
        } catch (Exception e) {
            LOGGER.error("[minio] Minio Metric Collection, Upload metric fail. Time consuming:{}",  System.currentTimeMillis() - l);
            throw e;
        }
    }

    /**
     * 监控删除指标
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @ConditionalOnBean(MinioClient.class)
    @Around("execution(* io.minio.MinioClient.removeObject(..))")
    public Object removeMeter(ProceedingJoinPoint pjp) throws Throwable {
        long l = System.currentTimeMillis();

        try {
            Object proceed = pjp.proceed();
            LOGGER.info("[minio] Minio Metric Collection, Remove metric success. Time consuming:{}", System.currentTimeMillis() - l);
            return proceed;
        } catch (Exception e) {
            LOGGER.error("[minio] Minio Metric Collection, Remove metric fail. Time consuming:{}",  System.currentTimeMillis() - l);
            throw e;
        }
    }
}
